package com.code2roc.fastboot.framework.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.ttl.TransmittableThreadLocal;
import com.code2roc.fastboot.framework.config.SystemConfig;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.NetworkInterface;
import java.nio.charset.Charset;
import java.util.Enumeration;
import java.util.UUID;

public class CommonUtil {
    public static String getNewLine() {
        return System.getProperty("line.separator");
    }

    public static String getNewGuid() {
        String dateStr = DateUtil.getDateTagToSecond();
        String randomStr = UUID.randomUUID().toString();
        try{
            randomStr = EncryptUtil.encryptByMD5(randomStr).toLowerCase();
        }catch (Exception e){
            e.printStackTrace();
        }
        return dateStr + randomStr;
    }

    public static String getExceptionString(Exception e) {
        StringBuilder builder = new StringBuilder();
        builder.append(e.toString() + getNewLine());
        StackTraceElement[] stackTraceElements = e.getStackTrace();
        for (StackTraceElement element : stackTraceElements) {
            builder.append(element.toString() + getNewLine());
        }
        return builder.toString();
    }

    public static String getThrowableString(Throwable e) {
        StringBuilder builder = new StringBuilder();
        builder.append(e.toString() + getNewLine());
        StackTraceElement[] stackTraceElements = e.getStackTrace();
        for (StackTraceElement element : stackTraceElements) {
            builder.append(element.toString() + getNewLine());
        }
        return builder.toString();
    }

    public static String getApiPath() {
        HttpServletRequest request = getRequest();
        String requestURL = request.getRequestURL().toString();
        String scheme = request.getScheme();
        String servaerName = request.getServerName();
        int port = request.getServerPort();
        String rootPageURL = scheme + ":" + "//" + servaerName + ":" + port + "/";
        return rootPageURL;
    }

    public static String getRootPath() {
        SystemConfig systemConfig = BeanUtil.getBean(SystemConfig.class);
        HttpServletRequest request = CommonUtil.getRequest();
        String requestURL = request.getRequestURL().toString();
        String scheme = request.getScheme();
        String servaerName = request.getServerName();
        int port = request.getServerPort();
        String rootPageURL = scheme + ":" + "//" + servaerName + ":" + port + "/"+systemConfig.getSystemTag()+"/";
        return rootPageURL;
    }

    ///region requet相关
    public static TransmittableThreadLocal<HttpServletRequest> requestTransmittableThreadLocal = new TransmittableThreadLocal<HttpServletRequest>();

    public static void shareRequest(HttpServletRequest request) {
        requestTransmittableThreadLocal.set(request);
    }

    public static HttpServletRequest getRequest() {
        HttpServletRequest request = requestTransmittableThreadLocal.get();
        if (request != null) {
            return requestTransmittableThreadLocal.get();
        } else {
            ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            if (requestAttributes != null) {
                return requestAttributes.getRequest();
            } else {
                return null;
            }
        }
    }

    public static void remove() {
        requestTransmittableThreadLocal.remove();
    }

    public static Object getRequestBodyPostParam(String paramName) {
        HttpServletRequest request = getRequest();
        Object paramValue;
        String body = "";
        try {
            body = getBodyString(request);
            JSONObject obj = JSON.parseObject(body);
            paramValue = obj.get(paramName);
        } catch (Exception e) {
            paramValue = "";
        }
        return paramValue;
    }

    public static String getRequestURL() {
        HttpServletRequest request = getRequest();
        if(request==null){
            return "";
        }else{
            return request.getRequestURL().toString();
        }

    }

    public static Object getRequestHeadParam(String paramName) {
        HttpServletRequest request = getRequest();
        return request.getHeader(paramName);
    }

    public static String getBodyString(HttpServletRequest request) throws IOException {
        StringBuilder sb = new StringBuilder();
        InputStream inputStream = null;
        BufferedReader reader = null;
        try {
            inputStream = request.getInputStream();
            reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));
            String line = "";
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return sb.toString();
    }
    ///endregion

    public static String getMacAddress() {
        try {
            Enumeration<NetworkInterface> el = NetworkInterface
                    .getNetworkInterfaces();
            while (el.hasMoreElements()) {
                byte[] mac = el.nextElement().getHardwareAddress();
                if (mac == null)
                    continue;
                String hexstr = bytesToHexString(mac);
                return getSplitString(hexstr, "-", 2).toUpperCase();
            }
        } catch (Exception exception) {
            exception.printStackTrace();
        }
        return null;
    }

    private static String getSplitString(String str, String split, int length) {
        int len = str.length();
        StringBuilder temp = new StringBuilder();
        for (int i = 0; i < len; i++) {
            if (i % length == 0 && i > 0) {
                temp.append(split);
            }
            temp.append(str.charAt(i));
        }
        String[] attrs = temp.toString().split(split);
        StringBuilder finalMachineCode = new StringBuilder();
        for (String attr : attrs) {
            if (attr.length() == length) {
                finalMachineCode.append(attr).append(split);
            }
        }
        String result = finalMachineCode.toString().substring(0,
                finalMachineCode.toString().length() - 1);
        return result;
    }

    private static String bytesToHexString(byte[] src) {
        StringBuilder stringBuilder = new StringBuilder("");
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }
}
